package org.despair2D.ui.puppet 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.utils.getQualifiedClassName;
	import org.despair2D.debug.Logger;
	import org.despair2D.renderer.IView;
	import org.despair2D.resource.ILoader;
	import org.despair2D.resource.LoaderManager;
	import org.despair2D.ui.core.ComponentProxy;
	import org.despair2D.ui.puppet.supportClasses.ImagePuppetComp;
	
	import org.despair2D.core.ns_despair;
	use namespace ns_despair;
	
	[Event(name = "complete", type = "flash.events.Event")]
	
	/**
	 * @usage
	 * 
	 * @property
	 * 		1. ◇isEmpty
	 * 		2. ◇key
	 * 		3. ◇bitmapData
	 * 
	 * @method
	 * 		1. ◆embed
	 * 		2. ◆load
	 * 		3. ◆empty
	 */
public class ImagePuppet extends ComponentProxy 
{
	/**
	 * @param	alignCode		对齐代号
	 * @param	pivotOffsetX	X轴中心偏移值
	 * @param	pivotOffsetY	Y轴中心偏移值
	 */
	public function ImagePuppet( alignCode:int = 7, pivotOffsetX:Number = 0, pivotOffsetY:Number = 0 ) 
	{
		m_view          =  ImagePuppetComp.getImagePuppetComp()
		m_view.proxy    =  this
		m_alignCode     =  alignCode
		m_pivotOffsetX  =  pivotOffsetX
		m_pivotOffsetY  =  pivotOffsetY
	}
	
	
	/** ◇是否空画像 **/
	final public function get isEmpty() : Boolean { return Boolean(m_key == null) }
	
	/** ◇画像源名称 **/
	final public function get key() : String { return m_key }
	
	/** ◇画像数据 **/
	final public function get bitmapData() : BitmapData { return m_view.m_img.bitmapData }
	
	
	/**
	 * ◆嵌入
	 * @param	bitmapRef
	 * @param	cached
	 */
	public function embed( bitmapRef:Class, cached:Boolean = true ) : void
	{
		var key:String
		var BP:Bitmap
		var BA:BitmapData
		
		this.checkAndStopLoad()
		key  =  getQualifiedClassName(bitmapRef)
		BA   =  m_bitmapDataList[key]
		
		if (!BA)
		{
			try
			{
				BP = new bitmapRef()
			}
			
			catch (error:Error)
			{
				Logger.reportError(this, 'embed', '参数定义类型错误...!')
			}
			
			BA = BP.bitmapData
			if (cached)
			{
				m_bitmapDataList[key] =  BA
			}
		}
		
		BA = BA.clone()
		if (!this.isEmpty)
		{
			m_view.m_img.bitmapData.dispose()
		}
		
		m_view.m_img.bitmapData  =  BA
		m_key                    =  key
		this.adjustAlign()
	}
	
	/**
	 * ◆载入
	 * @param	url
	 * @param	cached
	 * @param	optional
	 */
	public function load( url:String, cached:Boolean = true, optional:Class = null ) : void
	{
		var BA:BitmapData
		
		this.checkAndStopLoad()
		BA = m_bitmapDataList[url]
		
		if (BA)
		{
			if (!this.isEmpty)
			{
				m_view.m_img.bitmapData.dispose()
			}
			
			m_view.m_img.bitmapData  =  BA
			m_key                    =  url
			
			this.adjustAlign()
			return
		}
		
		// 预载画像
		if(optional)
		{
			this.embed(optional)
		}
		
		m_cached  =  cached
		m_loader  =  LoaderManager.getInstance().getLoader(url)
		
		m_loader.addEventListener(Event.COMPLETE, onComplete)
		m_loader.addEventListener(IOErrorEvent.IO_ERROR, onFail)
	}
	
	/**
	 * ◆空置
	 */
	final public function empty() : void
	{
		this.checkAndStopLoad()
		if (!this.isEmpty)
		{
			m_view.m_img.bitmapData.dispose()
		}
		
		m_view.m_img.bitmapData  =  null
		m_key                    =  null
	}
	
	
	final ns_despair function onComplete( e:Event ) : void
	{
		var BA:BitmapData
		
		BA = (m_loader.data as Bitmap).bitmapData
		
		// 削除缓存
		if (!this.isEmpty && !m_bitmapDataList[m_key])
		{
			m_view.m_img.bitmapData.dispose()
		}
		
		if (m_cached)
		{
			m_bitmapDataList[m_loader.url] = BA
		}
		
		m_view.m_img.bitmapData  =  m_cached ? BA.clone() : BA
		m_key                    =  m_loader.url
		m_loader                 =  null
		
		this.adjustAlign()
		this.dispatchEvent(new Event(Event.COMPLETE))
	}
	
	final ns_despair function onFail( e:IOErrorEvent ) : void
	{
		Logger.reportWarning(this, 'onFail', 'IO: ' + m_loader.url)
		m_loader = null
	}
	
	final ns_despair function checkAndStopLoad() : void
	{
		if (m_loader)
		{
			m_loader.removeEventListener(Event.COMPLETE, onComplete)
			m_loader.removeEventListener(IOErrorEvent.IO_ERROR, onFail)
			m_loader = null
		}
	}
	
	final ns_despair function adjustAlign() : void
	{	
		switch(m_alignCode)
		{
			case 7:
				m_view.m_img.x = m_view.m_img.y = 0
				break
			case 8:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = 0
				break
			case 9:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = 0
				break
			case 4:
				m_view.m_img.x = 0
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 5:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 6:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = -m_view.m_img.height / 2
				break
			case 1:
				m_view.m_img.x = 0
				m_view.m_img.y = -m_view.m_img.height
				break
			case 2:
				m_view.m_img.x = -m_view.m_img.width / 2
				m_view.m_img.y = -m_view.m_img.height
				break
			case 3:
				m_view.m_img.x = -m_view.m_img.width
				m_view.m_img.y = -m_view.m_img.height
				break
			default:
				break
		}
		m_view.m_img.x -= m_pivotOffsetX
		m_view.m_img.y -= m_pivotOffsetY
	}
	
	final override ns_despair function get view() : IView
	{
		return m_view;
	}
	
	final override ns_despair function get shell() : DisplayObject
	{
		return m_view;
	}
	
	final override ns_despair function dispose() : void
	{
		this.empty()
		super.dispose();
		m_view.recycle()
		m_view = null
	}
	
	
	ns_despair static var m_bitmapDataList:Object = new Object()
	
	
	ns_despair var m_view:ImagePuppetComp
	
	ns_despair var m_loader:ILoader
	
	ns_despair var m_key:String
	
	ns_despair var m_alignCode:int
	
	ns_despair var m_cached:Boolean
	
	ns_despair var m_pivotOffsetX:Number, m_pivotOffsetY:Number
}
}